<?php

namespace app\model;

use think\helper\Str;
use think\Model;
use think\model\contract\Modelable;
use think\model\relation\HasMany;
use think\model\relation\HasOne;

class User extends Model
{
    public function card(): HasMany
    {
        return $this->hasMany(UserOilCard::class, 'uid', 'id');
    }

    public function fromSupplier(): HasOne
    {
        return $this->hasOne(Supplier::class, 'id', 'supplier');
    }

    public function saveData(): array
    {
        $param = request()->post();
        $count = $this->whereRaw("mobile = '$param[mobile]' or car_number = '$param[car_number]'")->when(!empty($param['id']), function ($query) use ($param) {
            $query->where('id', '<>', $param['id']);
        })->where('is_del', 1)->where('state', '<>', 3)->count();
        if ($count > 0) throw new \Exception('手机号/车牌号已存在');
        if (empty($param['id'])) {
            $password = setPassword("123456");
            $param['password'] = $password['password'];
            $param['code'] = $password['token'];
            $param['balance'] = 0;
            $param['freeze_balance'] = 0;
        }
        $this->exists(!empty($param['id']))->save($param);
        return $this->toArray();
    }

    public function addDriver(): array
    {
        $param = request()->post();
        $supplier = request()->supplier;
        $user = $param['user'];
        unset($param['user']);
        $items = array_map(function ($item) use ($supplier, $param) {
            if (empty($item['username']) || empty($item['mobile']) || empty($item['car_number'])) return null;
            unset($item['save']);
            $item['code'] = Str::random(18, 1);
            return array_merge($item, ['supplier' => $supplier['id'], 'add_user' => $supplier['name'], 'edit_user' => $supplier['name'], 'edit_time' => date("Y-m-d H:i:s")], $param);
        }, $user);
        $items = array_values(array_filter($items));
        $totalBalance = array_sum(array_column($items, 'balance'));
        if ($totalBalance > $supplier['balance']) throw new \Exception("分配余额不能超过账户余额");
        $this->startTrans();
        $this->saveAll($items);
        if ($totalBalance > 0) {
            //资金动向
            app(SupplierBalanceNotice::class)->save([
                "sid" => $supplier['id'],
                "money" => $totalBalance,
                "amount" => $supplier['balance'],
                "total" => (float)bcsub($supplier['balance'], $totalBalance, 2),
                "type" => 1,
                "order_sn" => date("Ymdhis") . Str::random(4, 1),
                "tag" => 2,
                "remark" => "司机开卡"
            ]);
            $supplier->dec("balance", $totalBalance)->inc("forzen_balance", $totalBalance)->save();
        }
        $this->commit();
        $ids = $this->whereIn('mobile', array_column($items, 'mobile'))->column("id", "mobile");
        $its = array_map(function ($item) use ($ids) {
            $id = $ids[$item['mobile']];
            if ($item['balance'] > 0) {
                return [
                    'uid' => $id,
                    'number' => date("YmdHis") . Str::random(6, 1),
                    'money' => $item['balance'],
                    'old_money' => 0,
                    'new_money' => $item['balance'],
                    'type' => 2,
                    'tag' => 1,
                    'remark' => '油卡开户'
                ];
            }
            return null;
        }, $user);
        app(UserBalanceDetail::class)->saveAll(array_values(array_filter($its)));
        return $items;
    }

    public function queryDriver(): int
    {
        $param = request()->param();
        return $this->whereRaw("mobile = '{$param['mobile']}' OR car_number = '{$param['car_number']}'")->count();
    }

    public function lst(): array
    {
        $param = request()->param();
        $data = $this->with(['fromSupplier' => function ($query) {
            $query->field("id,name");
        }])->when(!empty($param['code']), function ($query) use ($param) {
            $query->where('code', $param['code']);
        })->when(!empty($param['mobile']), function ($query) use ($param) {
            $query->where('mobile', $param['mobile']);
        })->when(!empty($param['name']), function ($query) use ($param) {
            $query->where('name', $param['name']);
        })->when(!empty($param['car_number']), function ($query) use ($param) {
            $query->where('car_number', $param['car_number']);
        })->when(!empty($param['state']), function ($query) use ($param) {
            $query->where('state', $param['state']);
        })->where('is_del', 1)->order('create_time', 'desc')->paginate(['list_rows' => $param['size'] ?? 30, 'page' => $param['page'] ?? 1])->toArray();
        return pageData($data);
    }

    public function download()
    {
        $data = $this->lst();
        $result = array_map(function ($item) {
            return [
                $item['code'],
                $item['car_number'],
                $item['username'],
                $item['mobile'],
                $item['idcard'],
                $item['state'] == 1 ? '有效' : '无效',
                $item['type'] == 1 ? '自有' : '外协',
                bcadd($item['balance'], $item['freeze_balance'], 2),
                $item['balance'],
                $item['freeze_balance'],
                $item['card_type'] == 1 ? '电子卡' : '实体卡',
                $item['pay_type'] == 1 ? '无密码' : '有密码',
                $item['add_user'],
                $item['create_time']
            ];
        }, $data['data']);
        $header = [
            '卡号',
            '车牌号',
            '姓名',
            '手机号',
            '身份证',
            '状态',
            '车辆类型',
            '油卡余额',
            '可用余额',
            '冻结金额',
            '卡形式',
            '验证方式',
            '创建人',
            '创建时间',
        ];
        $title = ['司机卡列表'];
        $file = "司机卡列表";
        $last_page = $data['last_page'];
        return excel(compact('result', 'header', 'title', 'file', 'last_page'));
    }

    public function detail()
    {
        $id = request()->param("id");
        return $this->where('id', $id)->find();
    }

    public function updateState()
    {
        $params = request()->param();
        $this->whereIn('id', $params['ids'])->update(['state' => $params['state']]);
        return $params;
    }

    public function deleteData()
    {
        $id = request()->param("ids");
        return $this->whereIn('id', $id)->update(['is_del' => 2]);
    }

    public function updateBalance(): array
    {
        $param = request()->param();
        $account = $this->where('id', $param['id'])->find();
        if (empty($account)) throw new \Exception("用户不存在");
        $this->startTrans();
        if ($param['tag'] == 1) $account->inc("balance", $param['money'])->save();
        else $account->dec("balance", $param['money'])->save();
        app(UserBalanceDetail::class)->save([
            "uid" => $account['id'],
            "number" => date("YmdHis") . Str::random(6, 1),
            "money" => $param['money'],
            "old_money" => $param['old_money'],
            "new_money" => $account->balance,
            "tag" => $param['tag'],
            "remark" => $param['remark'],
            "type" => $param['type']
        ]);
        $this->commit();
        return $account->toArray();
    }

    public function addDriverBalance(): array
    {
        $post = request()->post();
        $items = $this->whereIn("id", array_column($post, 'id'))->select()->toArray();
        $data = array_column($post, null, 'id');
        $update = [];
        $remarks = [];
        $supplier = request()->supplier;
        $this->startTrans();
        if (!empty($items)) {
            foreach ($items as $value) {
//                dd($data[$value['id']]);
                $update[] = [
                    'balance' => bcadd($value['balance'], $data[$value['id']]['amount'], 2),
                    'id' => $value['id']
                ];
                $remarks[] = [
                    'uid' => $value['id'],
                    'number' => date("YmdHis") . Str::random(6, 1),
                    'money' => $data[$value['id']]['amount'],
                    'old_money' => $value['balance'],
                    'new_money' => bcadd($value['balance'], $data[$value['id']]['amount'], 2),
                    'type' => 2,
                    'tag' => 1,
                    'remark' => $data[$value['id']]['purpose']
                ];
            }
        }
        if (!empty($update)) {
            $this->saveAll($update);
            app(UserBalanceDetail::class)->saveAll($remarks);
            $total = array_sum(array_column($post, 'amount'));
            app(SupplierBalanceNotice::class)->save([
                "sid" => $supplier['id'],
                "money" => $total,
                "amount" => $supplier['balance'],
                "total" => (float)bcsub($supplier['balance'], $total, 2),
                "type" => 1,
                "order_sn" => date("Ymdhis") . Str::random(4, 1),
                "tag" => 2,
                "remark" => "司机卡配额"
            ]);
            $supplier->dec("balance", $total)->inc("forzen_balance", $total)->save();
        }
        $this->commit();
        return [
            "total" => array_sum(array_column($post, 'amount')),
            "success" => count($update)
        ];
    }
}
